/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.gmi.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 *
 * @author Laurent WOUTERS
 */
public class Shape extends Element {
    private xowl.gmi.model.cvssl.Shape definition;
    private xowl.gmi.view.diagram.Shape widget;
    
    public Shape(Controller controller, Element parent, xowl.gmi.model.cvssl.Shape def) {
        super(controller, parent);
        this.definition = def;
        if (definition instanceof xowl.gmi.model.cvssl.Rectangle)
            init((xowl.gmi.model.cvssl.Rectangle)definition);
        else if (definition instanceof xowl.gmi.model.cvssl.Ellipse)
            init((xowl.gmi.model.cvssl.Ellipse)definition);
        else if (definition instanceof xowl.gmi.model.cvssl.Path)
            init((xowl.gmi.model.cvssl.Path)definition);
    }
    
    private xowl.interpreter.adapter.DataPropertyObserver getObserverWidth() {
        return new xowl.interpreter.adapter.DataPropertyObserver() {
            @Override public void onAdd(Object elem) {
                widget.setWidth((Integer)elem);
                controller.onDiagramUpdated();
            }
            @Override public void onRemove(Object elem) { }
        };
    }
    private xowl.interpreter.adapter.DataPropertyObserver getObserverHeight() {
        return new xowl.interpreter.adapter.DataPropertyObserver() {
            @Override public void onAdd(Object elem) {
                widget.setHeight((Integer)elem);
                controller.onDiagramUpdated();
            }
            @Override public void onRemove(Object elem) { }
        };
    }
    private xowl.interpreter.adapter.DataPropertyObserver getObserverBackgroundColor() {
        return new xowl.interpreter.adapter.DataPropertyObserver() {
            @Override public void onAdd(Object elem) {
                widget.setBackgroundColor(new java.awt.Color((Integer)elem));
                controller.onDiagramUpdated();
            }
            @Override public void onRemove(Object elem) { }
        };
    }
    private xowl.interpreter.adapter.DataPropertyObserver getObserverBorderColor() {
        return new xowl.interpreter.adapter.DataPropertyObserver() {
            @Override public void onAdd(Object elem) {
                widget.setBorderColor(new java.awt.Color((Integer)elem));
                controller.onDiagramUpdated();
            }
            @Override public void onRemove(Object elem) { }
        };
    }
    private xowl.interpreter.adapter.DataPropertyObserver getObserverBorderThickness() {
        return new xowl.interpreter.adapter.DataPropertyObserver() {
            @Override public void onAdd(Object elem) {
                widget.setBorderThickness((Integer)elem);
                controller.onDiagramUpdated();
            }
            @Override public void onRemove(Object elem) { }
        };
    }
    
    private void init(xowl.gmi.model.cvssl.Rectangle rectangle) {
        Integer width = getValueInteger(rectangle.getWidth(), getObserverWidth());
        if (width == null) width = 10;
        Integer height = getValueInteger(rectangle.getHeight(), getObserverHeight());
        if (height == null) height = 10;
        Boolean isFill = rectangle.getIsFill();
        if (isFill == null) isFill = false;
        java.awt.Color backgroundColor = getValueColor(rectangle.getFillColor(), getObserverBackgroundColor());
        java.awt.Color borderColor = getValueColor(rectangle.getBorderColor(), getObserverBorderColor());
        Integer thickness = getValueInteger(rectangle.getBorderThickness(), getObserverBorderThickness());
        if (thickness == null) thickness = 1;
        widget = new xowl.gmi.view.diagram.Rectangle(width, height, backgroundColor, borderColor, thickness, isFill);
    }
    private void init(xowl.gmi.model.cvssl.Ellipse ellipse) {
        Integer width = getValueInteger(ellipse.getWidth(), getObserverWidth());
        if (width == null) width = 10;
        Integer height = getValueInteger(ellipse.getHeight(), getObserverHeight());
        if (height == null) height = 10;
        Boolean isFill = ellipse.getIsFill();
        if (isFill == null) isFill = false;
        java.awt.Color backgroundColor = getValueColor(ellipse.getFillColor(), getObserverBackgroundColor());
        java.awt.Color borderColor = getValueColor(ellipse.getBorderColor(), getObserverBorderColor());
        Integer thickness = getValueInteger(ellipse.getBorderThickness(), getObserverBorderThickness());
        if (thickness == null) thickness = 1;
        widget = new xowl.gmi.view.diagram.Ellipse(width, height, backgroundColor, borderColor, thickness, isFill);
    }
    private void init(xowl.gmi.model.cvssl.Path path) {
        List<xowl.gmi.model.cvssl.Point> elems = new ArrayList<>(path.getAllPoints());
        Collections.sort(elems, new Comparator<xowl.gmi.model.cvssl.Point>() {
            public int compare(xowl.gmi.model.cvssl.Point o1, xowl.gmi.model.cvssl.Point o2) {
                return o1.getIndex() - o2.getIndex();
            }
        });
        int[] xpoints = new int[elems.size()];
        int[] ypoints = new int[elems.size()];
        for (int i=0; i!=elems.size(); i++) {
            xpoints[i] = getValueInteger(elems.get(i).getX(), null);
            ypoints[i] = getValueInteger(elems.get(i).getY(), null);
        }
        java.awt.Color backgroundColor = getValueColor(path.getFillColor(), getObserverBackgroundColor());
        java.awt.Color borderColor = getValueColor(path.getBorderColor(), getObserverBorderColor());
        Integer thickness = getValueInteger(path.getBorderThickness(), getObserverBorderThickness());
        if (thickness == null) thickness = 1;
        widget = new xowl.gmi.view.diagram.Circuit(xpoints, ypoints, backgroundColor, borderColor, thickness, false);
    }
    
    @Override public xowl.gmi.view.diagram.Widget getWidget() { return widget; }
    
    @Override protected int getContainedASTCount() { return 0; }
    @Override protected int getLeftSiblingsASTCount(Element divider) { return 0; }
    @Override protected boolean insertAST(xowl.gmi.model.ast.ASTNode node) { return false; }
    @Override protected ASTRemovalStatus removeAST(xowl.gmi.model.ast.ASTNode node) { return ASTRemovalStatus.NodeNotFound; }
    
    @Override public void saveTo(xowl.gmi.model.Diagram diagram) { }
    @Override public void decommission() { }
}
